package com.lpit.zookeeper;

import lombok.Data;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.shaded.com.google.common.collect.Maps;

import javax.annotation.PostConstruct;
import java.util.Map;

@Data
public class ZooKeeperClient {

    private String sequencePath;
    private String host;
    //创建连接实例
    private CuratorFramework cf;
    // 重试休眠时间
    private final int SLEEP_TIME_MS = 1000;
    // 最大重试100次
    private final int MAX_RETRIES = 100;
    //会话超时时间
    private final int SESSION_TIMEOUT = 30 * 1000;
    //连接超时时间
    private final int CONNECTION_TIMEOUT = 3 * 1000;
    // 序列化集合
    private Map<String, ZkSequence> zkSequenceMap = Maps.newConcurrentMap();

    public ZooKeeperClient(String sequencePath, String host) {
        this.sequencePath = sequencePath;
        this.host = host;
    }


    /**
     * 建立连接并启动Curator
     */
    @PostConstruct
    public void init() {
        this.cf = CuratorFrameworkFactory.builder()
                .connectString(this.getHost())              //设置zk server 地址端口192.168.0.29:2181,192.168.0.xxx:2181(可以设置多个)
                .connectionTimeoutMs(CONNECTION_TIMEOUT) //设置连接超时时间，单位毫秒ms
                .sessionTimeoutMs(SESSION_TIMEOUT)      //设置session会话超时时间，单位毫秒ms
                //重试策略retryPolicy；ExponentialBackoffRetry是一种策略设置重试休眠时间和最大重试次数
                .retryPolicy(new ExponentialBackoffRetry(SLEEP_TIME_MS, MAX_RETRIES))
                .build();
        /*开启*/
        this.cf.start();
        this.initZkSequence();
    }

    public void initZkSequence() {
        ZkSequenceEnum[] list = ZkSequenceEnum.values();
        for (int i = 0; i < list.length; i++) {
            String name = list[i].name();
            String path = this.sequencePath + name;
            ZkSequence zkSequence = new ZkSequence(this.cf, path);
            zkSequenceMap.put(name, zkSequence);
        }

    }

    public Long sequence(ZkSequenceEnum zkSequenceEnum) throws Exception {
        ZkSequence zkSequence = zkSequenceMap.get(zkSequenceEnum.name());
        if (zkSequence != null) {
            return zkSequence.sequence();
        }
        return null;
    }

}
